#include "tcpserver.hpp"
#include <memory>
using namespace tcpserver;
static void Usage(std::string proc)
{
    std::cerr << "Usage:\n\t" << proc << " port\r\n\r\n";
}
bool cal(const Request &req, Response &resp)
{
    resp.exitcode = OK;
    resp.result = OK;
    switch (req.op)
    {
    case '+':
        resp.result = req.x + req.y;
        break;
    case '-':
        resp.result = req.x - req.y;
        break;
    case '*':
        resp.result = req.x * req.y;
        break;
    case '/':
    {
        if (req.y == 0)
            resp.exitcode = DIV_ZERO;
        else
            resp.result = req.x / req.y;
    }
    break;
    case '%':
    {
        if (req.y == 0)
            resp.exitcode = MOD_ZERO;
        else
            resp.result = req.x % req.y;
    }
    break;
    default:
        resp.exitcode = OP_ERROR;
        break;
    }
    return true;
}
void Calculate(Connection *conn)
{
    std::string onePackage;
    while (ParseOnePackage(conn->inbuffer_, &onePackage))
    {
        std::string reqStr;
        if (!deLength(onePackage, &reqStr))
            return;
        std::cout << "去掉报头的正文: \n"
                  << reqStr << std::endl;
        Request req;
        if (!req.deserialize(reqStr))
            return;
        Response resp;
        cal(req, resp);
        std::string respStr;
        resp.serialize(&respStr);
        conn->outbuffer_ += enLength(respStr);
        std::cout << "--------------result: " << conn->outbuffer_ << std::endl;
    }
    // 直接发
    if (conn->sender_)
        conn->sender_(conn);
    // 这有简洁写法看课
    //  如果没有发送完毕, 需要对对应的sock开启对写事件的关心, 如果发完了, 我们要关闭对写事件的关心
    // if (!conn->outbuffer_.empty())
    //     conn->tsp_->EnableReadWrite(conn, true, true);
    // else
    //     conn->tsp_->EnableReadWrite(conn, true, false);
}
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }
    std::unique_ptr<TcpServer> tsvr(new TcpServer(Calculate, atoi(argv[1])));
    tsvr->InitServer();
    tsvr->Dispatcher();
    return 0;
}